//
// Created by Administrator on 2021/12/5.
//

#include "Display.h"
#include <iostream>

static float c = 3.1415926 / 180.0f;
static float r = 1.0f;
static int degree = 90;

Display *Display::currentInstance = nullptr;

Display::Display(MarchingCubes *mc, int argc, char **argv) : mc(mc) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(200, 200);
    glutCreateWindow("Marching-Cubes");
    // 背景设为白色
    glClearColor(0, 0, 1, 1);
//    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
//    glutInitWindowSize(500, 500);
//    glutCreateWindow("ObjLoader");
//    glEnable(GL_DEPTH_TEST);
//    glShadeModel(GL_SMOOTH);
//
//    GLfloat lightPosition[] = {0.0f, 0.0f, 1.0f, 0.0f};
//    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
//    glEnable(GL_LIGHTING); //启用光源
//    glEnable(GL_LIGHT0);   //使用指定灯光
//
//    glEnable(GL_DEPTH_TEST);

}

void Display::display() {
//    glColor3f(1.0, 1.0, 1.0);
//    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//    glMatrixMode(GL_MODELVIEW);
//    glLoadIdentity();
//    glTranslatef(0.0f, 0.0f, -5.0f);
//
//    GLfloat lightPosition[] = {0.0f, 0.0f, 1.0f, 0.0f};
//    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
//    glEnable(GL_LIGHTING); //启用光源
//    glEnable(GL_LIGHT0);   //使用指定灯光
//
//    glPushMatrix();
//
//    gluLookAt(r * std::cos(c * degree), 0, r * std::cos(c * degree), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);

//    glClearColor(0.0, 0.0, 0.0, 0.0);
//    glDepthFunc(GL_LESS);
//    glEnable(GL_DEPTH_TEST);
//    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);//像素传输

    auto mesh = mc->get_mesh();
    auto indices = mesh->indices;
    auto vertices = mesh->vertices;

    glBegin(GL_TRIANGLES);
    for (int i = 0; i < mesh->indices.size(); i += 3) {
        GLfloat VN[3];

        GLfloat SV1[3], SV2[3], SV3[3];

        // 取出顶点索引
        GLint firstVertexIndex = indices.at(i) + 1;
        GLint secondVertexIndex = indices.at(i + 1) + 1;
        GLint thirdVertexIndex = indices.at(i + 2) + 1;

        // 第一个顶点
        SV1[0] = (vertices[firstVertexIndex]).x / 50;
        SV1[1] = (vertices[firstVertexIndex]).y/ 50;
        SV1[2] = (vertices[firstVertexIndex]).z/ 50;

        // 第二个顶点
        SV2[0] = (vertices[secondVertexIndex]).x/ 50;
        SV2[1] = (vertices[secondVertexIndex]).y/ 50;
        SV2[2] = (vertices[secondVertexIndex]).z/ 50;

        // 第三个顶点
        SV3[0] = (vertices[thirdVertexIndex]).x/ 50;
        SV3[1] = (vertices[thirdVertexIndex]).y/ 50;
        SV3[2] = (vertices[thirdVertexIndex]).z/ 50;

        GLfloat vec1[3], vec2[3], vec3[3];//计算法向量
        //(x2-x1,y2-y1,z2-z1)
        vec1[0] = SV1[0] - SV2[0];
        vec1[1] = SV1[1] - SV2[1];
        vec1[2] = SV1[2] - SV2[2];

        //(x3-x2,y3-y2,z3-z2)
        vec2[0] = SV1[0] - SV3[0];
        vec2[1] = SV1[1] - SV3[1];
        vec2[2] = SV1[2] - SV3[2];

        //(x3-x1,y3-y1,z3-z1)
        vec3[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
        vec3[1] = vec2[0] * vec1[2] - vec2[2] * vec1[0];
        vec3[2] = vec2[1] * vec1[0] - vec2[0] * vec1[1];

        GLfloat D = std::sqrt(vec3[0] * vec3[0] + vec3[1] * vec3[1] + vec3[2] * vec3[2]);

        VN[0] = vec3[0] / D;
        VN[1] = vec3[1] / D;
        VN[2] = vec3[2] / D;

        // 绘制法向量
        glNormal3f(VN[0], VN[1], VN[2]);

        // 绘制三角面片
        glVertex3f(SV1[0], SV1[1], SV1[2]);
        glVertex3f(SV2[0], SV2[1], SV2[2]);
        glVertex3f(SV3[0], SV3[1], SV3[2]);
    }

    glEnd();
    glPopMatrix();
    glutSwapBuffers();
}

void Display::exec() {
    setup_display_callback();
    glutMainLoop();
}
